package main

import (
	"fmt"
	"log"
	"os"
	"time"

	"goyolo/internal/config"
	"goyolo/internal/handler"
	"goyolo/internal/inference"

	"github.com/gin-gonic/gin"
)

func main() {
	// Load configuration
	cfg, err := config.LoadConfig()
	if err != nil {
		log.Fatalf("Failed to load configuration: %v", err)
	}

	// Initialize inference engine
	engine, err := inference.NewInferenceEngine(cfg)
	if err != nil {
		log.Fatalf("Failed to initialize inference engine: %v", err)
	}

	// Create Gin router
	router := gin.Default()

	// Add CORS middleware
	router.Use(corsMiddleware())

	// Initialize handlers
	h := handler.NewHandler(engine, cfg)

	// Health check endpoint
	router.GET("/health", h.HealthCheck)

	// Inference endpoints
	router.POST("/api/v1/infer", h.Infer)
	router.POST("/api/v1/infer/batch", h.InferBatch)
	router.POST("/api/v1/infer/upload", h.UploadAndInfer)

	// Model info endpoint
	router.GET("/api/v1/model/info", h.GetModelInfo)

	// Text detection endpoint
	router.POST("/api/v1/detect/text", h.DetectText)

	// Start server
	addr := fmt.Sprintf(":%d", cfg.Port)
	log.Printf("Starting YOLOv8 OpenVINO inference service on %s", addr)
	log.Printf("Model path: %s", cfg.ModelPath)
	log.Printf("C++ binary path: %s", cfg.CppBinaryPath)

	// Perform model warmup in background
	go func() {
		log.Printf("[WARMUP] Starting model warmup...")
		startTime := time.Now()
		if err := engine.WarmupModel(); err != nil {
			log.Printf("[WARMUP] Warning: Model warmup failed: %v", err)
		} else {
			duration := time.Since(startTime).Seconds()
			log.Printf("[WARMUP] Model warmup completed successfully in %.2f seconds", duration)
		}
	}()

	if err := router.Run(addr); err != nil {
		log.Fatalf("Failed to start server: %v", err)
	}
}

// corsMiddleware returns a CORS middleware for Gin
func corsMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
		c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
		c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")
		c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT, DELETE, PATCH")
		c.Writer.Header().Set("Access-Control-Max-Age", "86400")

		if c.Request.Method == "OPTIONS" {
			c.AbortWithStatus(204)
			return
		}

		c.Next()
	}
}

func init() {
	// Set Gin mode based on environment
	if os.Getenv("GIN_MODE") == "" {
		gin.SetMode(gin.DebugMode)
	}
}
